package com.neusoft.mid.msf.common.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.beanutils.converters.*;
import org.aspectj.weaver.ast.Var;
import org.springframework.beans.BeanUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @program: pangu
 * @description: 实体类相关工具类
 * 解决问题:1跨苏对实体的常驻字段:如 crtUser,crtHost,updUser等值的快速注入
 * @author: fengjd
 * @create: 2022-07-21 19:53
 **/
@Slf4j
public class EntityUtils {

    static {
        ConvertUtils.register(new ByteConverter(null), Byte.class);
        ConvertUtils.register(new CharacterConverter(null), Byte.class);
        ConvertUtils.register(new ShortConverter(null), Byte.class);
        ConvertUtils.register(new IntegerConverter(null), Byte.class);
        ConvertUtils.register(new LongConverter(null), Byte.class);
        ConvertUtils.register(new FloatConverter(null), Byte.class);
        ConvertUtils.register(new DoubleConverter(null), Byte.class);
        ConvertUtils.register(new BigDecimalConverter(null), Byte.class);
        ConvertUtils.register(new DateConverter(null), Byte.class);
        ConvertUtils.register(new StringConverter(null), Byte.class);

    }

    private static String getCurrentUserName() {
        return BaseContexHandler.getName();
    }

    private static String getCurrentUserId() {
        return BaseContexHandler.getUserID();
    }

    public static <T> void setCreatAndUpdatInfo(T entity) {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = servletRequestAttributes == null ? null : servletRequestAttributes.getRequest();
        String hostIp = "";
        String name = "";
        String id = "";
        if (request != null) {
            hostIp = String.valueOf(request.getHeader("userHost"));
            name = getCurrentUserName();
            id = getCurrentUserId();
        }
//        默认属性
        String[] fields = {"crtName", "crtUser", "crtHost", "crtTime"};
       Field field= ReflectionUtils.getAccessibleField(entity,"crtTime");

       // 默认值
        Object[] value = null;
        if (field!=null && field.getType(Date.class)) {
            value = new Object[]{name,id,hostIp,new Date()};
        }else if (field!=null && field.getType().equals(String.class)) {
            value =  new Object[]{name,id,hostIp,DateUtils.getCurrentDateTime()};
        }

//填充默认属性
        setDefaultValues(entity, fields, value);

    }

    public static <T> void setUpdatedInfo(T entity){
        ServletRequestAttributes servletRequestAttributes=(ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = servletRequestAttributes == null ? null : servletRequestAttributes.getRequest();
        String hostIp="",name="",id="";
        if (request!=null) {
            hostIp = String.valueOf(request.getHeader("userHost"));
            name  = getCurrentUserName();
            id = getCurrentUserId();
        }
//        默认属性
        String [] fields = {"updName","updUser","updHost","updTime" };
        Field field = ReflectionUtils.getAccessibleField(entity,"updTime");
        Object[] value = null;
        if (field!=null && field.getType().equals(Date.class)) {
            value =  new Object[]{name,id,hostIp,new Date()};
        }else if (field !=null && field.getType().equals(String.class)) {
            value = new Object[]{name,id,hostIp,DateUtils.getCurrentDateTime()};
        }
        setDefaultValues(entity,field,value);

    }

    /**
     * 依据对象的额属性数组和值数组对对象的属性进行赋值
     * @param entity
     * @param fields
     * @param value
     * @param <T>
     */
    private static <T> void setDefaultValues(T entity, String [] fields, Object[] value) {
        for (int i = 0; i < fields.length; i++) {
            String field = fields[i];
            if (ReflectionUtils.hasField(entity,field)){
                ReflectionUtils.invokeSetter(entity,field,value[i]);
            }
        }

    }


    public static <T> boolean isPKNotNull(T entity,String field){
       if( RefectionUtils.hasField(entity,field)){
           return false;
       }
       Object value= RefectionUtils.getFieldValue(entity,field);
        return  value != null && !"".equals(value);
    }


    /**
     * 把Bean中的内容导出成map
     *
     * @param bean
     * @return
     */
    public static Map<String,Object> describe(Object bean){
        Map<String,Object> param= null;
        if (bean!=null) {
            PropertyDescriptor[] propertyDescriptors = PropertyUtils.getPropertyDescriptors(bean);
            param = new HashMap<>();

            try {
                for (PropertyDescriptor descriptor : propertyDescriptors) {
                    String name = descriptor.getName();
                    Object value = PropertyUtils.getProperty(bean, name);
                    param.put(name, value);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        return param;
    }

    /**
     * 实现bean的复制功能
     * @param dest
     * @param orig
     * @param <T>
     */
    public static <T> void copyProperties(Object dest,Object orig){
        try {
            BeanUtils.copyProperties(orig,dest);
        } catch (Exception e) {
            log.error("Error copying properties",e);
        }

    }
}
